﻿Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Globalization
Imports System.Runtime.InteropServices
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Public Class ActivityBindTypeConverter
        Inherits TypeConverter
        ' Methods
        Public Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean
            Dim realContext As ITypeDescriptorContext = Nothing
            Dim realTypeConverter As TypeConverter = Nothing
            Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
            If ((Not realTypeConverter Is Nothing) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) Then
                Return realTypeConverter.CanConvertFrom(realContext, sourceType)
            End If
            Return ((sourceType Is GetType(String)) OrElse MyBase.CanConvertFrom(context, sourceType))
        End Function

        Public Overrides Function CanConvertTo(ByVal context As ITypeDescriptorContext, ByVal destinationType As Type) As Boolean
            If (((destinationType Is GetType(String)) AndAlso (Not context Is Nothing)) AndAlso ((Not context.PropertyDescriptor Is Nothing) AndAlso TypeOf context.PropertyDescriptor.GetValue(context.Instance) Is ActivityBind)) Then
                Return True
            End If
            Dim realContext As ITypeDescriptorContext = Nothing
            Dim realTypeConverter As TypeConverter = Nothing
            Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
            If ((Not realTypeConverter Is Nothing) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) Then
                Return realTypeConverter.CanConvertTo(realContext, destinationType)
            End If
            Return ((destinationType Is GetType(String)) OrElse MyBase.CanConvertTo(context, destinationType))
        End Function

        Public Overrides Function ConvertFrom(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal valueToConvert As Object) As Object
            Dim str As String = [TryCast](valueToConvert,String)
            If (str Is Nothing) Then
                Return MyBase.ConvertFrom(context, culture, valueToConvert)
            End If
            str = str.Trim
            Dim strArray As String() = Me.Parse(str)
            Dim obj2 As Object = If((strArray.Length = 2), New ActivityBind(strArray(0), strArray(1)), Nothing)
            If ((obj2 Is Nothing) AndAlso ((context Is Nothing) OrElse (context.PropertyDescriptor Is Nothing))) Then
                Return MyBase.ConvertFrom(context, culture, valueToConvert)
            End If
            If (Not obj2 Is Nothing) Then
                Return obj2
            End If
            Dim realContext As ITypeDescriptorContext = Nothing
            Dim realTypeConverter As TypeConverter = Nothing
            Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
            If (((Not realTypeConverter Is Nothing) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) AndAlso realTypeConverter.CanConvertFrom(realContext, GetType(String))) Then
                Return realTypeConverter.ConvertFrom(realContext, culture, str)
            End If
            Return valueToConvert
        End Function

        Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
            If (Not destinationType Is GetType(String)) Then
                Return MyBase.ConvertTo(context, culture, value, destinationType)
            End If
            Dim bind As ActivityBind = [TryCast](value,ActivityBind)
            If (Not bind Is Nothing) Then
                Dim component As Activity = [TryCast](PropertyDescriptorUtils.GetComponent(context),Activity)
                component = If((Not component Is Nothing), Helpers.ParseActivityForBind(component, bind.Name), Nothing)
                Return String.Format(CultureInfo.InvariantCulture, "Activity={0}, Path={1}", New Object() { If((Not component Is Nothing), component.QualifiedName, bind.Name), bind.Path })
            End If
            Dim realContext As ITypeDescriptorContext = Nothing
            Dim realTypeConverter As TypeConverter = Nothing
            Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
            If (((Not realTypeConverter Is Nothing) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) AndAlso realTypeConverter.CanConvertTo(realContext, destinationType)) Then
                Return [TryCast](realTypeConverter.ConvertTo(realContext, culture, value, destinationType),String)
            End If
            Return [TryCast](MyBase.ConvertTo(context, culture, value, destinationType),String)
        End Function

        Private Sub GetActualTypeConverterAndContext(ByVal currentContext As ITypeDescriptorContext, <Out> ByRef realTypeConverter As TypeConverter, <Out> ByRef realContext As ITypeDescriptorContext)
            realContext = currentContext
            realTypeConverter = Nothing
            If ((Not currentContext Is Nothing) AndAlso (Not currentContext.PropertyDescriptor Is Nothing)) Then
                realTypeConverter = TypeDescriptor.GetConverter(currentContext.PropertyDescriptor.PropertyType)
                Dim propertyDescriptor As ActivityBindPropertyDescriptor = [TryCast](currentContext.PropertyDescriptor,ActivityBindPropertyDescriptor)
                If (((Not propertyDescriptor Is Nothing) AndAlso (Not propertyDescriptor.RealPropertyDescriptor Is Nothing)) AndAlso ((Not propertyDescriptor.RealPropertyDescriptor.Converter Is Nothing) AndAlso (Not propertyDescriptor.RealPropertyDescriptor.Converter.GetType Is GetType(ActivityBindTypeConverter)))) Then
                    realTypeConverter = propertyDescriptor.RealPropertyDescriptor.Converter
                    realContext = New TypeDescriptorContext(currentContext, propertyDescriptor.RealPropertyDescriptor, currentContext.Instance)
                End If
            End If
        End Sub

        Public Overrides Function GetProperties(ByVal context As ITypeDescriptorContext, ByVal value As Object, ByVal attributes As Attribute()) As PropertyDescriptorCollection
            Dim list As New ArrayList
            If (TypeOf value Is ActivityBind AndAlso (Not context Is Nothing)) Then
                Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(value, New Attribute() { BrowsableAttribute.Yes })
                Dim realPropertyDescriptor As PropertyDescriptor = properties.Item("Name")
                If (Not realPropertyDescriptor Is Nothing) Then
                    list.Add(New ActivityBindNamePropertyDescriptor(context, realPropertyDescriptor))
                End If
                Dim descriptor2 As PropertyDescriptor = properties.Item("Path")
                If (Not descriptor2 Is Nothing) Then
                    list.Add(New ActivityBindPathPropertyDescriptor(context, descriptor2))
                End If
            ElseIf ((Not context Is Nothing) AndAlso (Not context.PropertyDescriptor Is Nothing)) Then
                Dim realContext As ITypeDescriptorContext = Nothing
                Dim realTypeConverter As TypeConverter = Nothing
                Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
                If ((Not realTypeConverter Is Nothing) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) Then
                    list.AddRange(realTypeConverter.GetProperties(realContext, value, attributes))
                End If
            End If
            Return New PropertyDescriptorCollection(DirectCast(list.ToArray(GetType(PropertyDescriptor)), PropertyDescriptor()))
        End Function

        Public Overrides Function GetPropertiesSupported(ByVal context As ITypeDescriptorContext) As Boolean
            Dim propertiesSupported As Boolean = False
            If ((Not context Is Nothing) AndAlso (Not context.PropertyDescriptor Is Nothing)) Then
                If TypeOf context.PropertyDescriptor.GetValue(context.Instance) Is ActivityBind Then
                    Return True
                End If
                Dim realContext As ITypeDescriptorContext = Nothing
                Dim realTypeConverter As TypeConverter = Nothing
                Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
                If ((Not realTypeConverter Is Nothing) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) Then
                    propertiesSupported = realTypeConverter.GetPropertiesSupported(realContext)
                End If
            End If
            Return propertiesSupported
        End Function

        Public Overrides Function GetStandardValues(ByVal context As ITypeDescriptorContext) As StandardValuesCollection
            Dim list As New ArrayList
            If ((context Is Nothing) OrElse (context.PropertyDescriptor Is Nothing)) Then
                Return New StandardValuesCollection(New ArrayList)
            End If
            Dim realContext As ITypeDescriptorContext = Nothing
            Dim realTypeConverter As TypeConverter = Nothing
            Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
            If (((Not realTypeConverter Is Nothing) AndAlso realTypeConverter.GetStandardValuesSupported(realContext)) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) Then
                list.AddRange(realTypeConverter.GetStandardValues(realContext))
            End If
            Return New StandardValuesCollection(list.ToArray)
        End Function

        Public Overrides Function GetStandardValuesExclusive(ByVal context As ITypeDescriptorContext) As Boolean
            Dim standardValuesExclusive As Boolean = False
            If ((Not context Is Nothing) AndAlso (Not context.PropertyDescriptor Is Nothing)) Then
                Dim obj2 As Object = If((Not context.Instance Is Nothing), context.PropertyDescriptor.GetValue(context.Instance), Nothing)
                If Not TypeOf obj2 Is ActivityBind Then
                    Dim realContext As ITypeDescriptorContext = Nothing
                    Dim realTypeConverter As TypeConverter = Nothing
                    Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
                    If ((Not realTypeConverter Is Nothing) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) Then
                        standardValuesExclusive = realTypeConverter.GetStandardValuesExclusive(realContext)
                    End If
                End If
            End If
            Return standardValuesExclusive
        End Function

        Public Overrides Function GetStandardValuesSupported(ByVal context As ITypeDescriptorContext) As Boolean
            Dim standardValuesSupported As Boolean = False
            If ((Not context Is Nothing) AndAlso (Not context.PropertyDescriptor Is Nothing)) Then
                Dim obj2 As Object = If((Not context.Instance Is Nothing), context.PropertyDescriptor.GetValue(context.Instance), Nothing)
                If Not TypeOf obj2 Is ActivityBind Then
                    Dim realContext As ITypeDescriptorContext = Nothing
                    Dim realTypeConverter As TypeConverter = Nothing
                    Me.GetActualTypeConverterAndContext(context, realTypeConverter, realContext)
                    If ((Not realTypeConverter Is Nothing) AndAlso (Not realTypeConverter.GetType Is GetType(ActivityBindTypeConverter))) Then
                        standardValuesSupported = realTypeConverter.GetStandardValuesSupported(realContext)
                    End If
                End If
            End If
            Return standardValuesSupported
        End Function

        Private Function Parse(ByVal value As String) As String()
            Dim strArray As String() = value.Split(New Char() { ","c }, 2)
            If (strArray.Length = 2) Then
                Dim str As String = "Activity="
                Dim str2 As String = "Path="
                Dim str3 As String = strArray(0).Trim
                Dim str4 As String = strArray(1).Trim
                If (str3.StartsWith(str, StringComparison.OrdinalIgnoreCase) AndAlso str4.StartsWith(str2, StringComparison.OrdinalIgnoreCase)) Then
                    str3 = str3.Substring(str.Length)
                    str4 = str4.Substring(str2.Length)
                    Return New String() { str3, str4 }
                End If
            End If
            Return New String(0  - 1) {}
        End Function

    End Class
End Namespace

